package edu.mse.camel.client.session.views;

import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import edu.mse.camel.client.eventbus.pubsub.EventManager;
import edu.mse.camel.client.events.server.QuerySessionListEvent;
import edu.mse.camel.client.events.server.QuerySessionListEvent.SessionList;
import edu.mse.camel.client.session.handlers.ReceiveInvitationEventHandler;
import edu.mse.camel.client.session.team.ITeamMember;
import edu.mse.camel.client.session.team.SESSION_CONSTANTS;
import edu.mse.camel.client.session.team.TEAMMEMBER_STATUS;
import edu.mse.camel.client.session.team.TeamList;
import edu.mse.camel.client.session.team.TeamVewConstants;

/**
 * This sample class demonstrates how to plug-in a new workbench view. The view
 * shows data obtained from the model. The sample creates a dummy model on the
 * fly, but a real implementation would connect to the model available either in
 * this or another plug-in (e.g. the workspace). The view is connected to the
 * model using a content provider.
 * <p>
 * The view uses a label provider to define how model objects should be
 * presented in the view. Each view can present the same model objects using
 * different labels and icons, if needed. Alternatively, a single label provider
 * can be shared between views in order to ensure that objects of the same type
 * are presented in the same way everywhere.
 * <p>
 */

public class TeamView extends ViewPart implements Observer {

	TableViewer viewer;

	private Display display;

	public static final String ONLINE_ICON = "icons/online_new.gif";
	public static final String OFFLINE_ICON = "icons/offline_new.gif";
	public static final String SESSION_ICON = "icons/session_new.gif";
	public static final String FACILITATOR_ICON = "icons/facilitator_new.gif";

	public static final String LOGIN_ICON = "icons/login.gif";
	public static final String LOGOUT_ICON = "icons/logout.gif";
	public static final String CREATE_ICON = "icons/create.gif";
	public static final String JOIN_ICON = "icons/join.gif";
	public static final String LEAVE_ICON = "icons/leave.gif";
	String selfStatus = "OFFLINE";

	ImageRegistry imageRegistry;

	/*
	 * The content provider class is responsible for providing objects to the
	 * view. It can wrap existing objects in adapters or simply return objects
	 * as-is. These objects may be sensitive to the current input of the view,
	 * or ignore it and always show the same content (like Task List, for
	 * example).
	 */

	class ViewLabelProvider extends LabelProvider implements
			ITableLabelProvider {

		public String getColumnText(Object obj, int index) {
			return getText(obj);
		}

		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}

		public Image getImage(Object obj) {

			if (obj instanceof ITeamMember) {
				ITeamMember tm = (ITeamMember) obj;
				if (tm.getStatus().equals(TEAMMEMBER_STATUS.ONLINE))
					return imageRegistry.get(TEAMMEMBER_STATUS.ONLINE
							.toString());
				else if (tm.getStatus().equals(TEAMMEMBER_STATUS.OFFLINE))
					return imageRegistry.get(TEAMMEMBER_STATUS.OFFLINE
							.toString());
				else if (tm.isFacilitator())
					return imageRegistry.get(ITeamMember.FACILITATOR);
				else
					return imageRegistry.get(TEAMMEMBER_STATUS.SESSION
							.toString());
			}
			return imageRegistry.get(TEAMMEMBER_STATUS.OFFLINE.toString());
		}
	}

	class NameSorter extends ViewerSorter {
	}

	ReceiveInvitationEventHandler rieHandler;
	
	/**
	 * The constructor.
	 */
	public TeamView() {
		imageRegistry = new ImageRegistry();
		imageRegistry.put(TEAMMEMBER_STATUS.ONLINE.toString(), ImageDescriptor
				.createFromFile(TeamView.class, ONLINE_ICON));
		imageRegistry.put(TEAMMEMBER_STATUS.OFFLINE.toString(),
				ImageDescriptor.createFromFile(TeamView.class, OFFLINE_ICON));
		imageRegistry.put(TEAMMEMBER_STATUS.SESSION.toString(),
				ImageDescriptor.createFromFile(TeamView.class, SESSION_ICON));
		imageRegistry.put(ITeamMember.FACILITATOR, ImageDescriptor
				.createFromFile(TeamView.class, FACILITATOR_ICON));
		imageRegistry.put(SESSION_CONSTANTS.LOGIN.toString(), ImageDescriptor
				.createFromFile(TeamView.class, LOGIN_ICON));
		imageRegistry.put(SESSION_CONSTANTS.LOGOUT.toString(),
				ImageDescriptor.createFromFile(TeamView.class, LOGOUT_ICON));
		imageRegistry.put(SESSION_CONSTANTS.CREATE.toString(),
				ImageDescriptor.createFromFile(TeamView.class, CREATE_ICON));
		imageRegistry.put(SESSION_CONSTANTS.JOIN.toString(), ImageDescriptor
				.createFromFile(TeamView.class, JOIN_ICON));
		imageRegistry.put(SESSION_CONSTANTS.LEAVE.toString(), ImageDescriptor
				.createFromFile(TeamView.class, LEAVE_ICON));
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider(this));
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());
		viewer.setInput(getViewSite());

		// Create the help context id for the viewer's control
		PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(),
				"TeamView.viewer");
		hookContextMenu();
	}

	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu1");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				TeamView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	private void fillContextMenu(IMenuManager manager) {
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
		IWorkbenchPartSite site = getSite();
		String message = "";

		if (TeamList.getInstance().getMe() != null) {

			if (site instanceof IViewSite) {
				if (TeamList.getInstance().getMyStatus().equals(
						TEAMMEMBER_STATUS.SESSION)) {
					message = TeamVewConstants.LOGIN_IN_SESSION_STATUS_MESSAGE
							+ TeamVewConstants.SESSION_ID_MESSAGE_SEPARATOR
							+ getSessionID(TeamList.getInstance().getMe());

					((IViewSite) site).getActionBars().getStatusLineManager()
							.setMessage(message);
				} else {
					((IViewSite) site)
							.getActionBars()
							.getStatusLineManager()
							.setMessage(
									TeamVewConstants.LOGIN_NOT_IN_SESSION_STATUS_MESSAGE);
				}
			}
		} else {
			((IViewSite) site)
					.getActionBars()
					.getStatusLineManager()
					.setMessage(
							TeamVewConstants.LOGIN_NOT_IN_SESSION_STATUS_MESSAGE);
		}
	}

	/**
	 * Gets the session information of the participant in session
	 * 
	 * @param teamMember
	 * 		, the team member
	 * @return
	 */
	private String getSessionID(ITeamMember teamMember) {
		QuerySessionListEvent qslEvent = new QuerySessionListEvent();
		EventManager.getInstance().dispatchEventSynchronous(qslEvent, true);
		List<SessionList> sessionList = qslEvent.getSessionList();
		String mySession = "";
		for (SessionList sList : sessionList) {
			List<String> participants = sList.getParticipants();
			if (participants != null) {
				for (String participant : participants) {
					if (participant.equalsIgnoreCase(teamMember.getName())) {
						mySession = sList.getsessionId().toString()
								+ TeamVewConstants.SESSION_ID_TITLE_SEPARATOR
								+ sList.getTitle();
						break;
					}
				}
			}
		}
		return mySession;
	}

	@Override
	public void update(Observable o, Object arg) {
		// viewer.refresh();
		display.syncExec(new Runnable() {
			@Override
			public void run() {
				viewer.refresh();
			}
		});
	}

}